package com.alias.app_interface;

import com.alias.DAOFactory.DAOFactory;
import com.alias.model.Employees;

import javax.swing.*;
import javax.swing.border.BevelBorder;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.*;
import java.nio.channels.FileChannel;
import java.sql.SQLException;
import java.util.*;
import java.util.List;

public class EmployeesTable extends JFrame implements ActionListener {

    private static EmployeesTable instance;
    private JFrame employeesTableForm;
    private JDialog aboutInfo;
    private JTable employeesTable;
    private JPanel topPanel;
    private JPanel statusPanel;
    private JButton addButton, editButton, deleteButton, loadButton, saveButton, queryButton;
    private JLabel statusLabel;
    private JFileChooser fc;
    private DefaultTableModel dftm;
    private List<Employees> employeesList;
    private List<Employees> tmpEmployeesList;
    private List<Employees> specifiedEmployeesList;
    private File file, backUpFile;
    private int rowIndex;
    private int columnIndex;
    private JButton yes;
    private JButton no;
    private JLabel aboutLabel;


    public EmployeesTable() {
        rowIndex = 0;
        columnIndex = 0;
        //employee list initialization
        employeesList = new ArrayList<Employees>();
        //form initialization
        employeesTableForm = new JFrame("Employees table");
        getEmployeesTableForm().setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        getEmployeesTableForm().setSize(700, 500);
        getEmployeesTableForm().setPreferredSize(new Dimension(700, 500));
        getEmployeesTableForm().addWindowListener(new WindowAdapter() {
            @Override
            public void windowOpened(WindowEvent windowEvent) {
                employeesList = DAOFactory.getInstance().getEmployeesDAO().getEmployeesList();
                tmpEmployeesList = employeesList;
                rowIndex = 0;
                for (Employees emp : employeesList) {
                    setEmployee(emp);
                }
                addButton.setEnabled(true);
                editButton.setEnabled(true);
                deleteButton.setEnabled(true);
                saveButton.setEnabled(true);
//                statusLabel.setText("Path : " + file.getAbsolutePath());
            }
        });
        getEmployeesTableForm().addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                instance = null;
            }
        });
        //dialog initialization
        aboutInfo = new JDialog();
        aboutInfo.setTitle("Are u sure");
        aboutInfo.setSize(270, 100);
        aboutInfo.setPreferredSize(new Dimension(270, 100));
        aboutLabel = new JLabel("Are u sure");
        yes = new JButton("Yes");
        no = new JButton("No");
        JPanel panel = new JPanel();
        panel.setLayout(new BoxLayout(panel, BoxLayout.LINE_AXIS));
        aboutInfo.add(aboutLabel, BorderLayout.PAGE_START);
        panel.setBorder(BorderFactory.createEmptyBorder(5, 40, 5, 40));
        panel.add(yes);
        panel.add(Box.createHorizontalGlue());
        panel.add(no);
        aboutInfo.add(panel, BorderLayout.CENTER);
        //top panel initialization
        topPanel = new JPanel();
        topPanel.setLayout(new BoxLayout(topPanel, BoxLayout.LINE_AXIS));
        topPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
        addButton = new JButton("Add");
        addButton.setEnabled(false);
        addButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                AdditionForm.getInstance("add");
                getEmployeesTableForm().setVisible(false);
            }
        });
        editButton = new JButton("Edit");
        editButton.setEnabled(false);
        editButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                AdditionForm.getInstance("edit");
                getEmployeesTableForm().setVisible(false);
            }
        });
        deleteButton = new JButton("Delete");
        deleteButton.setEnabled(false);
        deleteButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                aboutInfo.pack();
                aboutInfo.setVisible(true);
                yes.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        if ((getEmployeesList().size() != 0) && (employeesTable.getSelectedRow() != -1)) {
                            getEmployeesList().remove(employeesTable.getSelectedRow());
                            dftm.removeRow(employeesTable.getSelectedRow());
                            aboutInfo.setVisible(false);
                        } else {
                            aboutInfo.setVisible(false);
                            aboutInfo = new JDialog();
                            aboutInfo.setTitle("Deal with it");
                            aboutInfo.setSize(270, 100);
                            aboutInfo.setPreferredSize(new Dimension(270, 100));
                            JLabel aboutLabel = new JLabel("Nothink to delit =<");
                            aboutInfo.add(aboutLabel, BorderLayout.CENTER);
                            aboutInfo.pack();
                            aboutInfo.setVisible(true);
                        }
                    }
                });
                no.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        aboutInfo.setVisible(false);
                    }
                });

            }

        });
        queryButton = new JButton("Query");
        queryButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent actionEvent) {
                aboutInfo = new JDialog();
                aboutInfo.setVisible(false);
                aboutInfo = new JDialog();
                aboutInfo.setTitle("Deal with it");
                aboutInfo.setSize(270, 100);
                aboutInfo.setPreferredSize(new Dimension(270, 100));
                JLabel aboutLabel = new JLabel("Choose country to show");
                aboutInfo.add(aboutLabel, BorderLayout.CENTER);
                JComboBox comboBox = new JComboBox(new Object[]{"BELARUS", "RUSSIA", "USA", "GERMANY", "FRANCE"});
                comboBox.setSelectedItem("");
                aboutInfo.add(comboBox, BorderLayout.NORTH);
                aboutInfo.pack();
                aboutInfo.setVisible(true);
                comboBox.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent actionEvent) {
                        JComboBox comboBox1 = (JComboBox) actionEvent.getSource();
                        specifiedEmployeesList = DAOFactory.getInstance().getCountryDAO().getEmployeesSet(comboBox1.getSelectedItem().toString());
                        dftm.setRowCount(0);
                        rowIndex = 0;
                        for (Employees emp : specifiedEmployeesList) {
                            setEmployee(emp);
                        }
                    }
                });
                aboutInfo.addWindowListener(new WindowAdapter() {
                    @Override
                    public void windowClosing(WindowEvent windowEvent) {
                       setEmployeesList(employeesList);
                    }
                });
            }
        });
        loadButton = new JButton("Load");
        loadButton.addActionListener(this);
        saveButton = new JButton("Save");
        saveButton.setEnabled(false);
        saveButton.addActionListener(this);
        topPanel.add(addButton);
        topPanel.add(Box.createRigidArea(new Dimension(6, 0)));
        topPanel.add(editButton);
        topPanel.add(Box.createRigidArea(new Dimension(6, 0)));
        topPanel.add(deleteButton);
        topPanel.add(Box.createRigidArea(new Dimension(6, 0)));
        topPanel.add(queryButton);
        topPanel.add(Box.createHorizontalGlue());
        topPanel.add(loadButton);
        topPanel.add(Box.createRigidArea(new Dimension(6, 0)));
        topPanel.add(saveButton);
        topPanel.add(Box.createRigidArea(new Dimension(6, 0)));
        getEmployeesTableForm().add(topPanel, BorderLayout.PAGE_START);
        //status panel initialization
        statusPanel = new JPanel();
        statusPanel.setBorder(new BevelBorder(BevelBorder.LOWERED));
        getEmployeesTableForm().add(statusPanel, BorderLayout.PAGE_END);
        statusPanel.setPreferredSize(new Dimension(getEmployeesTableForm().getWidth(), 16));
        statusPanel.setLayout(new BoxLayout(statusPanel, BoxLayout.X_AXIS));
        statusLabel = new JLabel("Path :");
        statusLabel.setHorizontalAlignment(SwingConstants.LEFT);
        statusPanel.add(statusLabel);
        //table initialization
        String[] columnNames = {"Code", "Name", "Surname", "Birthday", "Country", "City", "Salary"};
        DefaultTableCellRenderer rightRenderer = new DefaultTableCellRenderer();
        rightRenderer.setHorizontalAlignment(JLabel.RIGHT);
        DefaultTableCellRenderer centerRenderer = new DefaultTableCellRenderer();
        centerRenderer.setHorizontalAlignment(JLabel.CENTER);
        dftm = new DefaultTableModel(columnNames, 0);
        employeesTable = new JTable(dftm);
        JScrollPane scrollPane = new JScrollPane(employeesTable);
        employeesTable.getColumnModel().getColumn(3).setCellRenderer(centerRenderer);
        employeesTable.getColumnModel().getColumn(6).setCellRenderer(rightRenderer);
        employeesTable.setFillsViewportHeight(true);
        employeesTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        getEmployeesTableForm().add(scrollPane, BorderLayout.CENTER);
        //finnalization
        pack();
        getEmployeesTableForm().setVisible(true);
        instance = this;
    }

    public JFrame getEmployeesTableForm() {
        return employeesTableForm;
    }

    public List<Employees> getEmployeesList() {
        return employeesList;
    }

    public void setEmployee(Employees employee) {
        dftm.setRowCount(rowIndex + 1);
        columnIndex = 0;
        dftm.setValueAt(employee.getCode(), rowIndex, columnIndex++);
        dftm.setValueAt(employee.getName(), rowIndex, columnIndex++);
        dftm.setValueAt(employee.getSurname(), rowIndex, columnIndex++);
        dftm.setValueAt(employee.getStringBirthday(), rowIndex, columnIndex++);
        dftm.setValueAt(employee.getStringCountry(), rowIndex, columnIndex++);
        dftm.setValueAt(employee.getCity(), rowIndex, columnIndex++);
        dftm.setValueAt(employee.getStringSalaryCurrency() + " " + employee.getSalaryAmount(), rowIndex, columnIndex++);
        rowIndex++;
    }
    public void addEmployee (Employees employee){
        this.employeesList.add(employee);
        try {
            DAOFactory.getInstance().getEmployeesDAO().addEmployee(employee);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        rowIndex = 0;
        for (Employees emp : employeesList) {
            setEmployee(emp);
        }
    }

    public static EmployeesTable getInstance() {
        return instance;
    }

    public void setEmployeesList(List<Employees> employeesList) {
        this.employeesList = employeesList;
//        tmpEmployeesList = new ArrayList<Employees>(employeesList);
        DAOFactory.getInstance().getEmployeesDAO().updateEmployees(employeesList);
//        this.employeesList.clear();
        dftm.setRowCount(0);
        rowIndex = 0;
        for (Employees emp : employeesList) {
            setEmployee(emp);
        }
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if (e.getActionCommand().equals("Load")) {
            fc = new JFileChooser();
            int returnVal = fc.showOpenDialog(EmployeesTable.this);

            if (returnVal == JFileChooser.APPROVE_OPTION) {
                file = fc.getSelectedFile();
                //This is where a real application would open the file.
            }
            try {
                ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file));
                List<Employees> tempEmployeesList;
                tempEmployeesList = (List<Employees>) ois.readObject();
                ois.close();
                getEmployeesList().clear();
                dftm.setRowCount(0);
                rowIndex = 0;
                for (Employees emp : tempEmployeesList) {
                    setEmployee(emp);
                }
                addButton.setEnabled(true);
                editButton.setEnabled(true);
                deleteButton.setEnabled(true);
                saveButton.setEnabled(true);
                statusLabel.setText("Path : " + file.getAbsolutePath());
            } catch (NullPointerException npe) {
                npe.printStackTrace();
            } catch (EOFException e1) {
                List<Employees> tempEmployeesList = new ArrayList<Employees>();
                getEmployeesList().clear();
                dftm.setRowCount(0);
                rowIndex = 0;
                for (Employees emp : tempEmployeesList) {
                    setEmployee(emp);
                }
                addButton.setEnabled(true);
                editButton.setEnabled(true);
                deleteButton.setEnabled(true);
                saveButton.setEnabled(true);
                statusLabel.setText("Path : " + file.getAbsolutePath());
                aboutInfo = new JDialog();
                aboutInfo.setTitle("Deal with it");
                aboutInfo.setSize(270, 100);
                aboutInfo.setPreferredSize(new Dimension(270, 100));
                JLabel aboutLabel = new JLabel("Nothink to load, create new blank table =<");
                aboutInfo.add(aboutLabel, BorderLayout.CENTER);
                aboutInfo.pack();
                aboutInfo.setVisible(true);
            } catch (IOException e1) {

                e1.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
            } catch (ClassNotFoundException e1) {
                e1.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
            }
        } else {
//            String fileName = file.getName();
            fc = new JFileChooser();
            int returnVal = fc.showSaveDialog(EmployeesTable.this);

            if (returnVal == JFileChooser.APPROVE_OPTION) {
                file = fc.getSelectedFile();
                //This is where a real application would open the file.
            }
            String backupFileName = file.getAbsolutePath().substring(0, file.getAbsolutePath().length() - file.getName().length());
            backUpFile = new File(backupFileName + "backup.txt");
            if (!backUpFile.exists()) {
                try {
                    backUpFile.createNewFile();
                    FileChannel source = null;
                    FileChannel destination = null;
                    source = new FileInputStream(file).getChannel();
                    destination = new FileOutputStream(backUpFile).getChannel();
                    destination.transferFrom(source, 0, source.size());
                    if(source != null) {
                        source.close();
                    }
                    if(destination != null) {
                        destination.close();
                    }
                } catch (IOException e1) {
                    e1.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
                }
            }
            file.delete();
            final JDialog aboutInfo = new JDialog();
            final JLabel aboutLabel = new JLabel("Are u sure what you want save file to: " + file.getPath());
            final JPanel panel = new JPanel();
            JButton yes2 = new JButton("Yes");
            JButton no2 = new JButton("No");
            panel.setLayout(new BoxLayout(panel, BoxLayout.LINE_AXIS));
            aboutInfo.add(aboutLabel, BorderLayout.PAGE_START);
            panel.setBorder(BorderFactory.createEmptyBorder(5, 40, 5, 40));
            panel.add(yes2);
            panel.add(Box.createHorizontalGlue());
            panel.add(no2);
            aboutInfo.add(panel, BorderLayout.CENTER);
            aboutInfo.pack();
            aboutInfo.setVisible(true);
            yes2.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    try {
                        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file));
                        file.createNewFile();
                        oos.writeObject(getEmployeesList());
                        backUpFile.delete();
                        oos.close();
                        panel.setVisible(false);
                        aboutLabel.setText("The data was successfully saved to " + file.getAbsolutePath());
                        aboutInfo.pack();
                        aboutInfo.setVisible(true);
                    } catch (IOException e1) {
                        file = backUpFile;
                        panel.setVisible(false);
                        aboutLabel.setText("Operation failed!");
                        aboutInfo.pack();
                        aboutInfo.setVisible(true);
                    }
                }
            });
            no2.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    aboutInfo.setVisible(false);
                }
            });

        }
    }
}
